package com.house.service.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.house.common.context.BaseContext;
import com.house.common.context.Dictionaries;
import com.house.common.exception.HouseException;
import com.house.common.properties.JwtProperties;
import com.house.common.properties.WeChatProperties;
import com.house.common.result.HttpCodeEnum;
import com.house.model.dto.UserLoginDto;
import com.house.model.entity.House;
import com.house.model.entity.SubscribeLookHouse;
import com.house.model.entity.User;
import com.house.model.vo.UserLoginVO;
import com.house.model.vo.UserSubscribeLevelVo;
import com.house.service.mapper.HouseMapper;
import com.house.service.mapper.SubscribeLookHouseMapper;
import com.house.service.mapper.UserMapper;
import com.house.service.service.IUserService;
import com.house.util.HttpClientUtil;
import com.house.util.JwtClaimsConstant;
import com.house.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {

    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private WeChatProperties weChatProperties;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private HouseMapper houseMapper;

    @Autowired
    private SubscribeLookHouseMapper subscribeLookHouseMapper;


    @Override
    public UserLoginVO wxLogin(UserLoginDto dto) {
        // 调用微信接口服务，获得当前微信用户的openid
        Object openid = getOpenid(dto);
        // 判断openid是否为空,如果为空抛出业务异常
        if (openid == null) {
            throw new HouseException(HttpCodeEnum.LOGIN_ERROR);
        }
        // 判断当前用户是否为新用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,dto.getPhone());
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            String userId = UUID.randomUUID().toString();
            user = user.builder()
                    .name(Dictionaries.DEFAULT_USER_NAME)
                    .userId(userId)
                    .openid((String) openid)
                    .phone(dto.getPhone())
                    .profilePhoto(Dictionaries.DEFALUT_IMAGE)
                    .states(Dictionaries.DEFAULT_USER_STATES)
                    .build();
            // 新增用户
            userMapper.insert(user);
        }
        if(user.getStates().equals("0")){
            throw new HouseException(HttpCodeEnum.USER_STATES_ERROR);
        }
        // 为微信用户生成jwt令牌
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID,user.getUserId());
        String jwt = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);

        BaseContext.setCurrentId(user.getUserId());

        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setUserId(user.getUserId());
        userLoginVO.setOpenid(user.getOpenid());
        userLoginVO.setToken(jwt);
        return userLoginVO;
    }

    @Override
    public User getUserInfo() {
        String userId = BaseContext.getCurrentId();
        if (userId == null) {
            throw new HouseException(HttpCodeEnum.NOT_LOGIN);
        }
        return userMapper.selectById(userId);
    }

    //修改用户
    @Override
    public void updateByUser(User user) {

        userMapper.updateByUser(user);
    }

    //修改密码
    @Override
    public void updateByUserPassWord(String password) {
        String userId = BaseContext.getCurrentId();
        userMapper.updateByUserPassWord(userId,password);

    }

    @Override
    public UserSubscribeLevelVo getUserSubscribeLevel(String houseId) {
        UserSubscribeLevelVo userSubscribeLevelVo = new UserSubscribeLevelVo();
        // 获取到房屋用户ID
        House house = houseMapper.selectById(houseId);
        String userId = house.getUserId();
        User user = userMapper.selectById(userId);
        userSubscribeLevelVo.setUserId(user.getUserId());
        userSubscribeLevelVo.setName(user.getName());
        userSubscribeLevelVo.setImage(user.getProfilePhoto());
        // 获取预约评分
        LambdaQueryWrapper<SubscribeLookHouse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SubscribeLookHouse::getToUserId,user.getUserId());
        List<SubscribeLookHouse> subscribeLookHouses = subscribeLookHouseMapper.selectList(wrapper);
        int count = 0;
        for (SubscribeLookHouse subscribeLookHouse : subscribeLookHouses) {
            if(subscribeLookHouse.getStarLevel() != null) count += subscribeLookHouse.getStarLevel();
        }

        double v = count > 0 ? count * 1.0 / subscribeLookHouses.size() : count;
        DecimalFormat decimalFormat = new DecimalFormat("0.0");
        String format = decimalFormat.format(v);
        userSubscribeLevelVo.setLevel(format);
        return userSubscribeLevelVo;
    }


    private Object getOpenid(UserLoginDto dto) {
        HashMap<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", dto.getAppcode());
        map.put("grant_type", "authorization_code");
        String s = HttpClientUtil.doGet(WX_LOGIN, map);
        JSONObject jsonObject = JSON.parseObject(s);
        Object openid = jsonObject.get("openid");
        return openid;
    }

}
